home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / OutOfPhase1.1 Source / OutOfPhase Folder / SampleList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  26.6 KB  |  923 lines  |  [TEXT/KAHL]

  1. /* SampleList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleList.h"
  31. #include "Memory.h"
  32. #include "StringList.h"
  33. #include "Array.h"
  34. #include "SampleObject.h"
  35. #include "Alert.h"
  36. #include "DataMunging.h"
  37. #include "PcodeSystem.h"
  38. #include "BufferedFileInput.h"
  39. #include "BufferedFileOutput.h"
  40. #include "Files.h"
  41. #include "Scrap.h"
  42. #include "InstrList.h"
  43.  
  44.  
  45. struct SampleListRec
  46.     {
  47.         StringListRec*                    List;
  48.         struct CodeCenterRec*        CodeCenter;
  49.         struct MainWindowRec*        MainWindow;
  50.         ArrayRec*                                SampleArray;
  51.         MyBoolean                                SampleListChanged;
  52.     };
  53.  
  54.  
  55. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe SampleObjectScrap")
  56.  
  57.  
  58. SampleListRec*            NewSampleList(struct MainWindowRec* MainWindow,
  59.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  60.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  61.     {
  62.         SampleListRec*        SampList;
  63.  
  64.         SampList = (SampleListRec*)AllocPtrCanFail(sizeof(SampleListRec),"SampleListRec");
  65.         if (SampList == NIL)
  66.             {
  67.              FailurePoint1:
  68.                 return NIL;
  69.             }
  70.         SampList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  71.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Samples");
  72.         if (SampList->List == NIL)
  73.             {
  74.              FailurePoint2:
  75.                 ReleasePtr((char*)SampList);
  76.                 goto FailurePoint1;
  77.             }
  78.         SampList->SampleArray = NewArray();
  79.         if (SampList->SampleArray == NIL)
  80.             {
  81.              FailurePoint3:
  82.                 DisposeStringList(SampList->List);
  83.                 goto FailurePoint2;
  84.             }
  85.         SampList->CodeCenter = CodeCenter;
  86.         SampList->MainWindow = MainWindow;
  87.         SampList->SampleListChanged = False;
  88.         return SampList;
  89.     }
  90.  
  91.  
  92. /* delete the sample list and all of the samples it contains */
  93. void                                DisposeSampleList(SampleListRec* SampList)
  94.     {
  95.         long                            Scan;
  96.         long                            Limit;
  97.  
  98.         CheckPtrExistence(SampList);
  99.         Limit = ArrayGetLength(SampList->SampleArray);
  100.         for (Scan = 0; Scan < Limit; Scan += 1)
  101.             {
  102.                 SampleObjectRec*    SampleTemp;
  103.  
  104.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  105.                 DisposeSampleObject(SampleTemp);
  106.             }
  107.         DisposeArray(SampList->SampleArray);
  108.         DisposeStringList(SampList->List);
  109.         ReleasePtr((char*)SampList);
  110.     }
  111.  
  112.  
  113. /* change the location of the sample list in the window */
  114. void                                SetSampleListLocation(SampleListRec* SampList,
  115.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  116.     {
  117.         CheckPtrExistence(SampList);
  118.         SetStringListLoc(SampList->List,XLoc,YLoc,Width,Height);
  119.     }
  120.  
  121.  
  122. /* redraw the list */
  123. void                                SampleListRedraw(SampleListRec* SampList)
  124.     {
  125.         CheckPtrExistence(SampList);
  126.         RedrawStringList(SampList->List);
  127.     }
  128.  
  129.  
  130. /* see if the specified coordinates falls inside the sample list rectangle */
  131. MyBoolean                        SampleListHitTest(SampleListRec* SampList,
  132.                                             OrdType XLoc, OrdType YLoc)
  133.     {
  134.         CheckPtrExistence(SampList);
  135.         return StringListHitTest(SampList->List,XLoc,YLoc);
  136.     }
  137.  
  138.  
  139. /* handle a mouse down event for the sample list */
  140. void                                SampleListDoMouseDown(SampleListRec* SampList, OrdType XLoc,
  141.                                             OrdType YLoc, ModifierFlags Modifiers)
  142.     {
  143.         CheckPtrExistence(SampList);
  144.         if (StringListMouseDown(SampList->List,XLoc,YLoc,Modifiers))
  145.             {
  146.                 /* if it returns true, then it was a double click */
  147.                 SampleListOpenSelection(SampList);
  148.             }
  149.     }
  150.  
  151.  
  152. /* called when the window becomes active */
  153. void                                SampleListBecomeActive(SampleListRec* SampList)
  154.     {
  155.         CheckPtrExistence(SampList);
  156.         EnableStringList(SampList->List);
  157.     }
  158.  
  159.  
  160. /* called when the window becomes inactive */
  161. void                                SampleListBecomeInactive(SampleListRec* SampList)
  162.     {
  163.         CheckPtrExistence(SampList);
  164.         DisableStringList(SampList->List);
  165.     }
  166.  
  167.  
  168. /* called when a selection is made in another list, so that this list */
  169. /* is deselected */
  170. void                                SampleListDeselect(SampleListRec* SampList)
  171.     {
  172.         CheckPtrExistence(SampList);
  173.         DeselectAllStringListElements(SampList->List);
  174.     }
  175.  
  176.  
  177. /* check to see if there is a selection in this list */
  178. MyBoolean                        SampleListIsThereSelection(SampleListRec* SampList)
  179.     {
  180.         CheckPtrExistence(SampList);
  181.         return (GetStringListHowManySelectedItems(SampList->List) > 0);
  182.     }
  183.  
  184.  
  185. /* check to see if any of the samples contained in this list need to be saved */
  186. MyBoolean                        DoesSampleListNeedToBeSaved(SampleListRec* SampList)
  187.     {
  188.         long                            Scan;
  189.         long                            Limit;
  190.         MyBoolean                    Flag;
  191.  
  192.         CheckPtrExistence(SampList);
  193.         Flag = SampList->SampleListChanged;
  194.         Limit = ArrayGetLength(SampList->SampleArray);
  195.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  196.             {
  197.                 SampleObjectRec*    SampleTemp;
  198.  
  199.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  200.                 if (HasSampleObjectBeenModified(SampleTemp))
  201.                     {
  202.                         Flag = True;
  203.                     }
  204.             }
  205.         return Flag;
  206.     }
  207.  
  208.  
  209. /* open an edit window for the selected sample */
  210. void                                SampleListOpenSelection(SampleListRec* SampList)
  211.     {
  212.         ArrayRec*                    ListOfSelections;
  213.  
  214.         CheckPtrExistence(SampList);
  215.         ListOfSelections = GetListOfSelectedItems(SampList->List);
  216.         if (ListOfSelections != NIL)
  217.             {
  218.                 long                            Scan;
  219.                 long                            Limit;
  220.  
  221.                 Limit = ArrayGetLength(ListOfSelections);
  222.                 for (Scan = 0; Scan < Limit; Scan += 1)
  223.                     {
  224.                         SampleObjectRec*        SampleTemp;
  225.  
  226.                         SampleTemp = (SampleObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  227.                         SampleObjectOpenWindow(SampleTemp);
  228.                     }
  229.                 DisposeArray(ListOfSelections);
  230.             }
  231.     }
  232.  
  233.  
  234. /* create a new sample and open a window for it */
  235. void                                SampleListNewSample(SampleListRec* SampList)
  236.     {
  237.         SampleObjectRec*    Sample;
  238.  
  239.         CheckPtrExistence(SampList);
  240.         /* create the object */
  241.         Sample = NewSampleObject(SampList->CodeCenter,SampList->MainWindow,SampList);
  242.         if (Sample == NIL)
  243.             {
  244.              FailurePoint1:
  245.                 AlertHalt("There is not enough memory available to create a new sample.",NIL);
  246.                 return;
  247.             }
  248.         /* add it to the string list */
  249.         if (!InsertStringListElement(SampList->List,NIL,NIL,Sample,True))
  250.             {
  251.              FailurePoint2:
  252.                 DisposeSampleObject(Sample);
  253.                 goto FailurePoint1;
  254.             }
  255.         MainWindowDeselectAllOtherStringLists(SampList->MainWindow,SampList);
  256.         SelectStringListElement(SampList->List,Sample);
  257.         MakeStringListSelectionVisible(SampList->List);
  258.         /* add it to the array */
  259.         if (!ArrayAppendElement(SampList->SampleArray,Sample))
  260.             {
  261.              FailurePoint3:
  262.                 RemoveStringListElement(SampList->List,Sample,True);
  263.                 goto FailurePoint2;
  264.             }
  265.         /* update our internal flags */
  266.         SampList->SampleListChanged = True;
  267.         /* change the name in the list */
  268.         SampleListSampleNameChanged(SampList,Sample);
  269.         /* show the window */
  270.         SampleObjectOpenWindow(Sample);
  271.     }
  272.  
  273.  
  274. /* delete the selected sample */
  275. void                                SampleListDeleteSelection(SampleListRec* SampList)
  276.     {
  277.         ArrayRec*                    ListOfSelections;
  278.  
  279.         CheckPtrExistence(SampList);
  280.         ListOfSelections = GetListOfSelectedItems(SampList->List);
  281.         if (ListOfSelections != NIL)
  282.             {
  283.                 long                                Scan;
  284.                 long                                Limit;
  285.  
  286.                 Limit = ArrayGetLength(ListOfSelections);
  287.                 for (Scan = 0; Scan < Limit; Scan += 1)
  288.                     {
  289.                         SampleObjectRec*    OneToZap;
  290.  
  291.                         OneToZap = (SampleObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  292.                         SampleListDeleteSample(SampList,OneToZap);
  293.                     }
  294.                 DisposeArray(ListOfSelections);
  295.             }
  296.     }
  297.  
  298.  
  299. /* delete the explicitly specified sample */
  300. void                                SampleListDeleteSample(SampleListRec* SampList,
  301.                                             struct SampleObjectRec* TheSample)
  302.     {
  303.         long                                Scan;
  304.         long                                Limit;
  305.  
  306.         CheckPtrExistence(SampList);
  307.         MainWindowClearInstrObjects(SampList->MainWindow);
  308.         Limit = ArrayGetLength(SampList->SampleArray);
  309.         for (Scan = 0; Scan < Limit; Scan += 1)
  310.             {
  311.                 SampleObjectRec*        SampleTemp;
  312.  
  313.                 SampleTemp = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  314.  
  315.                 if (TheSample == SampleTemp)
  316.                     {
  317.                         FileSpec*                    BackupFileWhere;
  318.                         FileType*                    BackupFile;
  319.                         MyBoolean                    Success = False;
  320.  
  321.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  322.                             CODE4BYTES('?','?','?','?'));
  323.                         if (BackupFileWhere != NIL)
  324.                             {
  325.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  326.                                     {
  327.                                         BufferedOutputRec*    Output;
  328.  
  329.                                         Output = NewBufferedOutput(BackupFile);
  330.                                         if (Output != NIL)
  331.                                             {
  332.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  333.                                                     MAGICSCRAPSTRING))
  334.                                                     {
  335.                                                         if (SampleObjectWriteOutData(TheSample,Output)
  336.                                                             == eFileLoadNoError)
  337.                                                             {
  338.                                                                 Success = True;
  339.                                                             }
  340.                                                     }
  341.                                                 if (!EndBufferedOutput(Output))
  342.                                                     {
  343.                                                         Success = False;
  344.                                                     }
  345.                                             }
  346.                                          else
  347.                                             {
  348.                                                 CloseFile(BackupFile);
  349.                                             }
  350.                                     }
  351.                                  else
  352.                                     {
  353.                                         DeleteFile(BackupFileWhere);
  354.                                         DisposeFileSpec(BackupFileWhere);
  355.                                     }
  356.                             }
  357.                         if (Success)
  358.                             {
  359.                                 MainWindowNewDeleteUndoInfo(SampList->MainWindow,BackupFileWhere,
  360.                                     BackupFile);
  361.                                 DisposeSampleObject(SampleTemp);
  362.                                 RemoveStringListElement(SampList->List,SampleTemp,True);
  363.                                 ArrayDeleteElement(SampList->SampleArray,Scan);
  364.                                 SampList->SampleListChanged = True;
  365.                             }
  366.                          else
  367.                             {
  368.                                 YesNoCancelType        Decision;
  369.  
  370.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  371.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  372.                                 if (Decision == eYes)
  373.                                     {
  374.                                         DisposeSampleObject(SampleTemp);
  375.                                         RemoveStringListElement(SampList->List,SampleTemp,True);
  376.                                         ArrayDeleteElement(SampList->SampleArray,Scan);
  377.                                         SampList->SampleListChanged = True;
  378.                                     }
  379.                             }
  380.                         return;
  381.                     }
  382.             }
  383.         EXECUTE(PRERR(AllowResume,"SampleListDeleteSample:  couldn't find object"));
  384.     }
  385.  
  386.  
  387. /* the name of a sample has changed, so the name in the scrolling */
  388. /* list must also be changed */
  389. void                                SampleListSampleNameChanged(SampleListRec* SampList,
  390.                                             struct SampleObjectRec* TheSample)
  391.     {
  392.         char*                            SampleName;
  393.  
  394.         CheckPtrExistence(SampList);
  395.         CheckPtrExistence(TheSample);
  396.         ERROR(ArrayFindElement(SampList->SampleArray,TheSample) < 0,
  397.             PRERR(ForceAbort,"SampleListSampleNameChanged:  unknown sample"));
  398.         SampleName = SampleObjectGetNameCopy(TheSample);
  399.         if (SampleName != NIL)
  400.             {
  401.                 char*                            SampleNameNullTerminated;
  402.  
  403.                 SampleNameNullTerminated = BlockToStringCopy(SampleName);
  404.                 if (SampleNameNullTerminated != NIL)
  405.                     {
  406.                         ChangeStringListElementName(SampList->List,
  407.                             SampleNameNullTerminated,TheSample);
  408.                         ReleasePtr(SampleNameNullTerminated);
  409.                     }
  410.                 ReleasePtr(SampleName);
  411.             }
  412.     }
  413.  
  414.  
  415. /* look for a specified sample.  returns NIL if not found.  the name is NOT null */
  416. /* terminated */
  417. SampleObjectRec*        SampleListLookupNamedSample(SampleListRec* SampList, char* Name)
  418.     {
  419.         long                            Scan;
  420.         long                            Limit;
  421.  
  422.         CheckPtrExistence(SampList);
  423.         CheckPtrExistence(Name);
  424.         Limit = ArrayGetLength(SampList->SampleArray);
  425.         for (Scan = 0; Scan < Limit; Scan += 1)
  426.             {
  427.                 SampleObjectRec*        Sample;
  428.                 char*                                NameCopy;
  429.  
  430.                 Sample = (SampleObjectRec*)ArrayGetElement(SampList->SampleArray,Scan);
  431.                 NameCopy = SampleObjectGetNameCopy(Sample);
  432.                 if (NameCopy != NIL)
  433.                     {
  434.                         if (PtrSize(Name) == PtrSize(NameCopy))
  435.                             {
  436.                                 if (MemEqu(Name,NameCopy,PtrSize(Name)))
  437.                                     {
  438.                                         ReleasePtr(NameCopy);
  439.                                         return Sample;
  440.                                     }
  441.                             }
  442.                         ReleasePtr(NameCopy);
  443.                     }
  444.             }
  445.         return NIL;
  446.     }
  447.  
  448.  
  449. SampleErrors                SampleListGetSampleLeftFixed(SampleListRec* SampList,
  450.                                             char* Name, largefixedsigned** DataOut)
  451.     {
  452.         SampleObjectRec*        Sample;
  453.  
  454.         CheckPtrExistence(SampList);
  455.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  456.             "SampleListGetSampleLeftFixed:  data out is NIL"));
  457.         Sample = SampleListLookupNamedSample(SampList,Name);
  458.         if (Sample == NIL)
  459.             {
  460.                 return eEvalSampleUndefined;
  461.             }
  462.         if (eSampleStereo != SampleObjectGetNumChannels(Sample))
  463.             {
  464.                 return eEvalSampleWrongChannel;
  465.             }
  466.         *DataOut = SampleObjectGetLeftFixed(Sample);
  467.         if (*DataOut == NIL)
  468.             {
  469.                 return eEvalSampleNotEnoughMemoryToCopy;
  470.             }
  471.         return eEvalSampleNoError;
  472.     }
  473.  
  474.  
  475. SampleErrors                SampleListGetSampleRightFixed(SampleListRec* SampList,
  476.                                             char* Name, largefixedsigned** DataOut)
  477.     {
  478.         SampleObjectRec*        Sample;
  479.  
  480.         CheckPtrExistence(SampList);
  481.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  482.             "SampleListGetSampleRightFixed:  data out is NIL"));
  483.         Sample = SampleListLookupNamedSample(SampList,Name);
  484.         if (Sample == NIL)
  485.             {
  486.                 return eEvalSampleUndefined;
  487.             }
  488.         if (eSampleStereo != SampleObjectGetNumChannels(Sample))
  489.             {
  490.                 return eEvalSampleWrongChannel;
  491.             }
  492.         *DataOut = SampleObjectGetRightFixed(Sample);
  493.         if (*DataOut == NIL)
  494.             {
  495.                 return eEvalSampleNotEnoughMemoryToCopy;
  496.             }
  497.         return eEvalSampleNoError;
  498.     }
  499.  
  500.  
  501. SampleErrors                SampleListGetSampleMonoFixed(SampleListRec* SampList,
  502.                                             char* Name, largefixedsigned** DataOut)
  503.     {
  504.         SampleObjectRec*        Sample;
  505.  
  506.         CheckPtrExistence(SampList);
  507.         ERROR(DataOut == NIL,PRERR(ForceAbort,
  508.             "SampleListGetSampleMonoFixed:  data out is NIL"));
  509.         Sample = SampleListLookupNamedSample(SampList,Name);
  510.         if (Sample == NIL)
  511.             {
  512.                 return eEvalSampleUndefined;
  513.             }
  514.         if (eSampleMono != SampleObjectGetNumChannels(Sample))
  515.             {
  516.                 return eEvalSampleWrongChannel;
  517.             }
  518.         *DataOut = SampleObjectGetMonoFixed(Sample);
  519.         if (*DataOut == NIL)
  520.             {
  521.                 return eEvalSampleNotEnoughMemoryToCopy;
  522.             }
  523.         return eEvalSampleNoError;
  524.     }
  525.  
  526.  
  527. /* use the provided data to open a new sample with the specified attributes. */
  528. /* this is used when opening an algorithmic sample as a data sample. */
  529. /* RawData MUST be valid. */
  530. SampleObjectRec*        SampleListCopyRawSampleAndOpen(SampleListRec* SampList,
  531.                                             char* RawData, NumBitsType NumBits, NumChannelsType NumChannels,
  532.                                             long Origin, long LoopStart1, long LoopStart2, long LoopStart3,
  533.                                             long LoopEnd1, long LoopEnd2, long LoopEnd3, long SamplingRate,
  534.                                             double NaturalFrequency)
  535.     {
  536.         SampleObjectRec*    Sample;
  537.  
  538.         CheckPtrExistence(SampList);
  539.         CheckPtrExistence(RawData);
  540.         /* create the object */
  541.         Sample = NewSampleObjectInitialized(SampList->CodeCenter,SampList->MainWindow,
  542.             SampList,RawData,NumBits,NumChannels,Origin,LoopStart1,LoopStart2,LoopStart3,
  543.             LoopEnd1,LoopEnd2,LoopEnd3,SamplingRate,NaturalFrequency);
  544.         if (Sample == NIL)
  545.             {
  546.              FailurePoint1:
  547.                 AlertHalt("There is not enough memory available to create a new sample.",NIL);
  548.                 return NIL;
  549.             }
  550.         /* add it to the string list */
  551.         if (!InsertStringListElement(SampList->List,NIL,NIL,Sample,True))
  552.             {
  553.              FailurePoint2:
  554.                 DisposeSampleObject(Sample);
  555.                 goto FailurePoint1;
  556.             }
  557.         MainWindowDeselectAllOtherStringLists(SampList->MainWindow,SampList);
  558.         SelectStringListElement(SampList->List,Sample);
  559.         MakeStringListSelectionVisible(SampList->List);
  560.         /* add it to the array */
  561.         if (!ArrayAppendElement(SampList->SampleArray,Sample))
  562.             {
  563.              FailurePoint3:
  564.                 RemoveStringListElement(SampList->List,Sample,True);
  565.                 goto FailurePoint2;
  566.             }
  567.         /* update our internal flags */
  568.         SampList->SampleListChanged = True;
  569.         /* change the name in the list */
  570.         SampleListSampleNameChanged(SampList,Sample);
  571.         /* show the window */
  572.         SampleObjectOpenWindow(Sample);
  573.         return Sample;
  574.     }
  575.  
  576.  
  577. /* the document's name has changed, so the windows have to be updated */
  578. void                                SampleListGlobalNameChange(SampleListRec* SampleList,
  579.                                             char* NewFilename)
  580.     {
  581.         long                            Scan;
  582.         long                            Limit;
  583.  
  584.         CheckPtrExistence(SampleList);
  585.         Limit = ArrayGetLength(SampleList->SampleArray);
  586.         for (Scan = 0; Scan < Limit; Scan += 1)
  587.             {
  588.                 SampleObjectRec*        Sample;
  589.  
  590.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  591.                 SampleObjectGlobalNameChange(Sample,NewFilename);
  592.             }
  593.     }
  594.  
  595.  
  596. /*   4-bytes little endian number of sample objects (positive 2s complement) */
  597. /*   n-bytes of data for the sampe objects */
  598.  
  599.  
  600. /* read sample objects from a file.  returns True if fully successful. */
  601. FileLoadingErrors        SampleListReadData(SampleListRec* SampleList,
  602.                                             struct BufferedInputRec* Input)
  603.     {
  604.         signed long                NumSampleObjects;
  605.         long                            Scan;
  606.  
  607.         CheckPtrExistence(SampleList);
  608.         CheckPtrExistence(Input);
  609.  
  610.         /*   4-bytes little endian number of sample objects */
  611.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumSampleObjects))
  612.             {
  613.                 return eFileLoadDiskError;
  614.             }
  615.         if (NumSampleObjects < 0)
  616.             {
  617.                 return eFileLoadBadFormat;
  618.             }
  619.  
  620.         /* load the objects */
  621.         for (Scan = 0; Scan < NumSampleObjects; Scan += 1)
  622.             {
  623.                 SampleObjectRec*    Sample EXECUTE(= (SampleObjectRec*)0x81818181);
  624.                 FileLoadingErrors    Error;
  625.  
  626.                 /* read the sample object from the file */
  627.                 Error = SampleObjectNewFromFile(&Sample,Input,SampleList->CodeCenter,
  628.                     SampleList->MainWindow,SampleList);
  629.                 if (Error != eFileLoadNoError)
  630.                     {
  631.                      FailurePoint1:
  632.                         return Error;
  633.                     }
  634.                 CheckPtrExistence(Sample);
  635.                 /* add it to the string list */
  636.                 if (!InsertStringListElement(SampleList->List,NIL,NIL,Sample,True))
  637.                     {
  638.                      FailurePoint2:
  639.                         DisposeSampleObject(Sample);
  640.                         Error = eFileLoadOutOfMemory;
  641.                         goto FailurePoint1;
  642.                     }
  643.                 /* add it to the array */
  644.                 if (!ArrayAppendElement(SampleList->SampleArray,Sample))
  645.                     {
  646.                      FailurePoint3:
  647.                         RemoveStringListElement(SampleList->List,Sample,True);
  648.                         goto FailurePoint2;
  649.                     }
  650.                 /* change the name in the list */
  651.                 SampleListSampleNameChanged(SampleList,Sample);
  652.             }
  653.  
  654.         return eFileLoadNoError;
  655.     }
  656.  
  657.  
  658. /* write sample objects to a file.  returns True if fully successful. */
  659. FileLoadingErrors        SampleListWriteData(SampleListRec* SampleList,
  660.                                             struct BufferedOutputRec* Output)
  661.     {
  662.         signed long                NumSampleObjects;
  663.         long                            Scan;
  664.  
  665.         CheckPtrExistence(SampleList);
  666.         CheckPtrExistence(Output);
  667.  
  668.         /*   4-bytes little endian number of sample objects (positive 2s complement) */
  669.         NumSampleObjects = ArrayGetLength(SampleList->SampleArray);
  670.         if (!WriteBufferedSignedLongLittleEndian(Output,NumSampleObjects))
  671.             {
  672.                 return eFileLoadDiskError;
  673.             }
  674.  
  675.         /* write out the samples */
  676.         for (Scan = 0; Scan < NumSampleObjects; Scan += 1)
  677.             {
  678.                 SampleObjectRec*        Sample;
  679.                 FileLoadingErrors        Error;
  680.  
  681.                 /* get the sample */
  682.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  683.                 /* write it out */
  684.                 Error = SampleObjectWriteOutData(Sample,Output);
  685.                 /* handle mishaps */
  686.                 if (Error != eFileLoadNoError)
  687.                     {
  688.                         return Error;
  689.                     }
  690.             }
  691.  
  692.         return eFileLoadNoError;
  693.     }
  694.  
  695.  
  696. /* after a file has been saved, this is called to mark all objects as not modified. */
  697. void                                SampleListMarkAllObjectsSaved(SampleListRec* SampleList)
  698.     {
  699.         long                            Scan;
  700.         long                            Limit;
  701.  
  702.         CheckPtrExistence(SampleList);
  703.         Limit = ArrayGetLength(SampleList->SampleArray);
  704.         for (Scan = 0; Scan < Limit; Scan += 1)
  705.             {
  706.                 SampleObjectRec*        Sample;
  707.  
  708.                 Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Scan);
  709.                 SampleObjectMarkAsSaved(Sample);
  710.             }
  711.         SampleList->SampleListChanged = False;
  712.     }
  713.  
  714.  
  715. /* copy the selected object in the list to the clipboard.  return False if failed. */
  716. MyBoolean                        SampleListCopyObject(SampleListRec* SampleList)
  717.     {
  718.         ArrayRec*                            ListOfSelections;
  719.         MyBoolean                            TotalSuccessFlag = False;
  720.  
  721.         CheckPtrExistence(SampleList);
  722.         ListOfSelections = GetListOfSelectedItems(SampleList->List);
  723.         if (ListOfSelections != NIL)
  724.             {
  725.                 if (ArrayGetLength(ListOfSelections) >= 1)
  726.                     {
  727.                         SampleObjectRec*        SampleTemp;
  728.                         FileSpec*                        TempFileLocation;
  729.  
  730.                         SampleTemp = (SampleObjectRec*)ArrayGetElement(ListOfSelections,0);
  731.                         /* open the temporary file */
  732.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  733.                             CODE4BYTES('\?','\?','\?','\?'));
  734.                         if (TempFileLocation != NIL)
  735.                             {
  736.                                 FileType*                            FileDescriptor;
  737.  
  738.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  739.                                     {
  740.                                         BufferedOutputRec*        BufferedFile;
  741.  
  742.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  743.                                         if (BufferedFile != NIL)
  744.                                             {
  745.                                                 MyBoolean                            WriteSucceeded = False;
  746.  
  747.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  748.                                                     MAGICSCRAPSTRING))
  749.                                                     {
  750.                                                         if (SampleObjectWriteOutData(SampleTemp,BufferedFile)
  751.                                                             == eFileLoadNoError)
  752.                                                             {
  753.                                                                 WriteSucceeded = True;
  754.                                                             }
  755.                                                     }
  756.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  757.                                                     {
  758.                                                         char*                            Buffer;
  759.                                                         long                            NumberOfBytes;
  760.  
  761.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  762.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  763.                                                             "SampleListCopyObject:  scrap buffer");
  764.                                                         if (Buffer != NIL)
  765.                                                             {
  766.                                                                 if (SetFilePosition(FileDescriptor,0))
  767.                                                                     {
  768.                                                                         if (0 == ReadFromFile(FileDescriptor,
  769.                                                                             Buffer,NumberOfBytes))
  770.                                                                             {
  771.                                                                                 if (SetScrapToThis(Buffer))
  772.                                                                                     {
  773.                                                                                         TotalSuccessFlag = True;
  774.                                                                                     }
  775.                                                                             }
  776.                                                                     }
  777.                                                                 ReleasePtr(Buffer);
  778.                                                             }
  779.                                                     }
  780.                                             }
  781.                                         CloseFile(FileDescriptor);
  782.                                     }
  783.                                 DeleteFile(TempFileLocation);
  784.                                 DisposeFileSpec(TempFileLocation);
  785.                             }
  786.                     }
  787.                 DisposeArray(ListOfSelections);
  788.             }
  789.         return TotalSuccessFlag;
  790.     }
  791.  
  792.  
  793. /* try to paste the clipboard in as a sample object.  returns False if it failed */
  794. /* or the clipboard did not contain a sample object. */
  795. MyBoolean                        SampleListPasteObject(SampleListRec* SampleList)
  796.     {
  797.         MyBoolean                    TotalSuccessFlag = False;
  798.         char*                            Scrap;
  799.  
  800.         CheckPtrExistence(SampleList);
  801.         Scrap = GetCopyOfScrap();
  802.         if (Scrap != NIL)
  803.             {
  804.                 FileSpec*                    TempFileLocation;
  805.  
  806.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  807.                     CODE4BYTES('\?','\?','\?','\?'));
  808.                 if (TempFileLocation != NIL)
  809.                     {
  810.                         FileType*                            FileDescriptor;
  811.  
  812.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  813.                             {
  814.                                 BufferedOutputRec*        BufferedFile;
  815.  
  816.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  817.                                 if (BufferedFile != NIL)
  818.                                     {
  819.                                         MyBoolean                            WriteSucceeded = False;
  820.  
  821.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  822.                                             {
  823.                                                 WriteSucceeded = True;
  824.                                             }
  825.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  826.                                             {
  827.                                                 TotalSuccessFlag = SampleListPasteFromFile(SampleList,
  828.                                                     FileDescriptor);
  829.                                             }
  830.                                     }
  831.                                 CloseFile(FileDescriptor);
  832.                             }
  833.                         DeleteFile(TempFileLocation);
  834.                         DisposeFileSpec(TempFileLocation);
  835.                     }
  836.                 ReleasePtr(Scrap);
  837.             }
  838.         return TotalSuccessFlag;
  839.     }
  840.  
  841.  
  842. /* paste a sample object in from the file */
  843. MyBoolean                        SampleListPasteFromFile(SampleListRec* SampleList,
  844.                                             struct FileType* File)
  845.     {
  846.         MyBoolean                    TotalSuccessFlag = False;
  847.  
  848.         CheckPtrExistence(SampleList);
  849.         if (SetFilePosition(File,0))
  850.             {
  851.                 BufferedInputRec*    InputFile;
  852.  
  853.                 InputFile = NewBufferedInput(File);
  854.                 if (InputFile != NIL)
  855.                     {
  856.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  857.  
  858.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  859.                             {
  860.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  861.                                     {
  862.                                         SampleObjectRec*            SampleTemp EXECUTE(= (SampleObjectRec*)0x81818181);
  863.  
  864.                                         if (eFileLoadNoError == SampleObjectNewFromFile(&SampleTemp,InputFile,
  865.                                             SampleList->CodeCenter,SampleList->MainWindow,SampleList))
  866.                                             {
  867.                                                 CheckPtrExistence(SampleTemp);
  868.                                                 /* add it to the scrolling object list */
  869.                                                 if (!InsertStringListElement(SampleList->List,NIL,NIL,SampleTemp,True))
  870.                                                     {
  871.                                                      FailurePoint:
  872.                                                         DisposeSampleObject(SampleTemp);
  873.                                                     }
  874.                                                  else
  875.                                                     {
  876.                                                         MainWindowDeselectAllOtherStringLists(SampleList->MainWindow,SampleList);
  877.                                                         SelectStringListElement(SampleList->List,SampleTemp);
  878.                                                         MakeStringListSelectionVisible(SampleList->List);
  879.                                                         /* add it to the array */
  880.                                                         if (!ArrayAppendElement(SampleList->SampleArray,SampleTemp))
  881.                                                             {
  882.                                                                 RemoveStringListElement(SampleList->List,SampleTemp,True);
  883.                                                                 goto FailurePoint;
  884.                                                             }
  885.                                                          else
  886.                                                             {
  887.                                                                 /* change the name in the list */
  888.                                                                 SampleListSampleNameChanged(SampleList,SampleTemp);
  889.                                                                 TotalSuccessFlag = True;
  890.                                                                 SampleList->SampleListChanged = True;
  891.                                                             }
  892.                                                     }
  893.                                             }
  894.                                     }
  895.                             }
  896.                         EndBufferedInput(InputFile);
  897.                     }
  898.             }
  899.         return TotalSuccessFlag;
  900.     }
  901.  
  902.  
  903. /* find out how many samples there are in this list */
  904. long                                SampleListHowMany(SampleListRec* SampleList)
  905.     {
  906.         CheckPtrExistence(SampleList);
  907.         return ArrayGetLength(SampleList->SampleArray);
  908.     }
  909.  
  910.  
  911. /* get an indexed sample from the list */
  912. struct SampleObjectRec*    SampleListGetIndexedSample(SampleListRec* SampleList, long Index)
  913.     {
  914.         SampleObjectRec*    Sample;
  915.  
  916.         CheckPtrExistence(SampleList);
  917.         ERROR((Index < 0) || (Index >= SampleListHowMany(SampleList)),PRERR(ForceAbort,
  918.             "SampleListGetIndexedSample:  index out of range"));
  919.         Sample = (SampleObjectRec*)ArrayGetElement(SampleList->SampleArray,Index);
  920.         CheckPtrExistence(Sample);
  921.         return Sample;
  922.     }
  923.